Introduction

Working through this tutorial on NetworkX. My version is a little differently ordered than the tut.

Set up environment


In [1]:
import networkx as nx
import matplotlib.pyplot as plt     # For visualising graphs
import pandas as pd                 # To see how nicely it plays with networkx
import numpy as np                  # To see how nicely it plays with networkx

In [2]:
def printGraphState(g):
    """
    Prints out the number of nodes, edges, and selfloops in the given graph (g)
    """
    print("# nodes: " + str(g.number_of_nodes()))
    print(g.nodes())
    print("# edges: " + str(g.number_of_edges()))
    print(g.edges())
    print("# self-loops: " + str(g.number_of_selfloops()))

Instantiate a Graph

A Graph is a collection of nodes (vertices) along with identified pairs of nodes (edges/links)


In [3]:
g = nx.Graph()
printGraphState(g)


# nodes: 0
[]
# edges: 0
[]
# self-loops: 0

Add some nodes


In [4]:
g.add_node(1)             # Add a single node
g.add_nodes_from([2,3])   # Add a list of nodes
g.add_nodes_from("Hello, world!")   # Add nodes from a string
printGraphState(g)


# nodes: 13
['!', 1, 2, 3, 'e', 'd', ' ', 'H', 'l', 'o', ',', 'r', 'w']
# edges: 0
[]
# self-loops: 0

Add a nbunch of nodes


In [5]:
g2 = nx.path_graph(10)
printGraphState(g2)
g.add_nodes_from(g2)     # Add the nodes from g2
g.add_node(g2)           # Add g2 as a node (graph of graphs)
printGraphState(g)


# nodes: 10
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# edges: 9
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9)]
# self-loops: 0
# nodes: 21
['!', 1, 2, 3, 'e', 'd', 0, ' ', 8, 'H', 7, 'l', 'o', ',', 'r', 'w', 9, 4, 6, <networkx.classes.graph.Graph object at 0x7f369d8047d0>, 5]
# edges: 0
[]
# self-loops: 0

Add edges

Add single edges


In [6]:
g.add_edge(1,2)
printGraphState(g)
e1 = (2,3)
g.add_edge(*e1)           # Unpacks the edge tuple
printGraphState(g)


# nodes: 21
['!', 1, 2, 3, 'e', 'd', 0, ' ', 8, 'H', 7, 'l', 'o', ',', 'r', 'w', 9, 4, 6, <networkx.classes.graph.Graph object at 0x7f369d8047d0>, 5]
# edges: 1
[(1, 2)]
# self-loops: 0
# nodes: 21
['!', 1, 2, 3, 'e', 'd', 0, ' ', 8, 'H', 7, 'l', 'o', ',', 'r', 'w', 9, 4, 6, <networkx.classes.graph.Graph object at 0x7f369d8047d0>, 5]
# edges: 2
[(1, 2), (2, 3)]
# self-loops: 0

Add a list of edges


In [7]:
g.add_edges_from([(1,2),(1,3)])
printGraphState(g)


# nodes: 21
['!', 1, 2, 3, 'e', 'd', 0, ' ', 8, 'H', 7, 'l', 'o', ',', 'r', 'w', 9, 4, 6, <networkx.classes.graph.Graph object at 0x7f369d8047d0>, 5]
# edges: 3
[(1, 2), (1, 3), (2, 3)]
# self-loops: 0

Add an ebunch (iterable container of edge-tuples) of edges


In [8]:
g.add_edges_from(g2.edges())
printGraphState(g)


# nodes: 21
['!', 1, 2, 3, 'e', 'd', 0, ' ', 8, 'H', 7, 'l', 'o', ',', 'r', 'w', 9, 4, 6, <networkx.classes.graph.Graph object at 0x7f369d8047d0>, 5]
# edges: 10
[(1, 0), (1, 2), (1, 3), (2, 3), (3, 4), (8, 9), (8, 7), (7, 6), (4, 5), (6, 5)]
# self-loops: 0

Remove nodes

Remove a single node


In [9]:
g.remove_node(g2)
printGraphState(g)


# nodes: 20
['!', 1, 2, 3, 'e', 'd', 0, ' ', 8, 'H', 7, 'l', 'o', ',', 'r', 'w', 9, 4, 6, 5]
# edges: 10
[(1, 0), (1, 2), (1, 3), (2, 3), (3, 4), (8, 9), (8, 7), (7, 6), (4, 5), (6, 5)]
# self-loops: 0

Remove nodes from


In [10]:
g.remove_nodes_from('Doll Howler')
printGraphState(g)


# nodes: 13
['!', 1, 2, 3, 'd', 0, 8, 7, ',', 9, 4, 6, 5]
# edges: 10
[(1, 0), (1, 2), (1, 3), (2, 3), (3, 4), (8, 9), (8, 7), (7, 6), (4, 5), (6, 5)]
# self-loops: 0

Show the neighbours of a node


In [11]:
g.neighbors(1)


Out[11]:
[0, 2, 3]

In [12]:
g.neighbors(0)


Out[12]:
[1]

Visualise some graphs


In [13]:
nx.draw(g)



In [14]:
nx.draw_random(g)



In [15]:
nx.draw_circular(g)



In [16]:
nx.draw_networkx(g)



In [17]:
nx.draw_shell(g)



In [18]:
nx.draw_spectral(g)



In [19]:
nx.draw_spring(g)


Clear the nodes


In [20]:
g.clear()
printGraphState(g)


# nodes: 0
[]
# edges: 0
[]
# self-loops: 0

Create a Digraph


In [21]:
printGraphState(g2)
dig = nx.DiGraph(g2)
printGraphState(dig)


# nodes: 10
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# edges: 9
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9)]
# self-loops: 0
# nodes: 10
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# edges: 18
[(0, 1), (1, 0), (1, 2), (2, 1), (2, 3), (3, 2), (3, 4), (4, 3), (4, 5), (5, 4), (5, 6), (6, 5), (6, 7), (7, 8), (7, 6), (8, 9), (8, 7), (9, 8)]
# self-loops: 0

Create a standard graph from a digraph


In [22]:
g3 = nx.Graph(dig.edges())
printGraphState(g3)


# nodes: 10
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# edges: 9
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9)]
# self-loops: 0

Examine numpy/Pandas objects as nodes


In [25]:
s = pd.Series([1,3,5,np.nan,6,8])
s


Out[25]:
0     1
1     3
2     5
3   NaN
4     6
5     8
dtype: float64

In [26]:
g = nx.Graph()
g.add_nodes_from(s)
printGraphState(g)


# nodes: 6
[nan, 1.0, 3.0, 5.0, 6.0, 8.0]
# edges: 0
[]
# self-loops: 0

From Pandas dataframe (as per docs)


In [38]:
r = np.random.RandomState(seed=3142)
ints = r.random_integers(1, 10, size=(3,2))
ints


Out[38]:
array([[ 4,  9],
       [10,  7],
       [ 1,  1]])

In [40]:
a = ['A', 'B', 'C']
b = ['D', 'A', 'E']
df = pd.DataFrame(ints, columns=['weight', 'cost'])
df


Out[40]:
weight cost
0 4 9
1 10 7
2 1 1

In [41]:
df[0] = a
df['b'] = b
df


Out[41]:
weight cost 0 b
0 4 9 A D
1 10 7 B A
2 1 1 C E

In [48]:
g=nx.from_pandas_dataframe(df, 0, 'b', ['weight', 'cost'])#,nx.DiGraph())
printGraphState(g)


# nodes: 5
['A', 'C', 'B', 'E', 'D']
# edges: 3
[('A', 'B'), ('A', 'D'), ('C', 'E')]
# self-loops: 0

In [49]:
nx.draw_networkx(g)


Access edges


In [53]:
g['A']


Out[53]:
{'B': {'cost': 7, 'weight': 10}, 'D': {'cost': 9, 'weight': 4}}

In [54]:
g['A']['B']


Out[54]:
{'cost': 7, 'weight': 10}

Set attributes of an edge


In [57]:
g['A']['B']['color']='purple'
g['A']['B']


Out[57]:
{'color': 'purple', 'cost': 7, 'weight': 10}

Examine all edges


In [70]:
g2 = nx.Graph()
g2.add_weighted_edges_from([(0,1,3.0),(1,2,7.5)])

In [71]:
for n,nbrs in g2.adjacency_iter():
    for nbr,eattr in nbrs.items():
        data = eattr['weight']
        if data < 4.0:
            print('(%d,%d,%.3f)' % (n,nbr,data))


(0,1,3.000)
(1,0,3.000)

In [72]:
for (u,v,d) in g2.edges(data="weight"):
    print('(%d,%d,%.3f)' % (n,nbr,data))


(2,1,7.500)
(2,1,7.500)

Attributes

Graph attributes


In [76]:
g = nx.Graph(foo="bar")
g.graph


Out[76]:
{'foo': 'bar'}

In [77]:
g.graph['foo'] = 'cbs'
g.graph


Out[77]:
{'foo': 'cbs'}

Node attributes


In [78]:
g.add_node(1,mantype='super')
g.add_nodes_from([-1], mantype='bat')

In [79]:
g.node[1]


Out[79]:
{'mantype': 'super'}

In [83]:
g.node[1]['home']='Krypton'
g.node[1]['fly']=True
g.nodes()


Out[83]:
[1, -1]

In [84]:
g.nodes(data=True)


Out[84]:
[(1, {'fly': True, 'home': 'Krypton', 'mantype': 'super'}),
 (-1, {'mantype': 'bat'})]

Edge attributes


In [90]:
g.add_edge(-1,1,weight = 1.1)
g.add_edges_from([(3,4),(4,5)], color='red')
g.add_edges_from([(-1,1,{'color':'blue'}),(2,3,{'weight':8})])
g[4][5]['weight'] = 2.3
g.edges(data=True)


Out[90]:
[(1, -1, {'color': 'blue', 'weight': 1.1}),
 (2, 3, {'weight': 8}),
 (3, 4, {'color': 'red'}),
 (4, 5, {'color': 'red', 'weight': 2.3})]

In [93]:
g2 = nx.complement(g)
g2.edges()


Out[93]:
[(1, 2),
 (1, 3),
 (1, 4),
 (1, 5),
 (2, 4),
 (2, 5),
 (2, -1),
 (3, 5),
 (3, -1),
 (4, -1),
 (5, -1)]

Some classic small graphs


In [96]:
petersen = nx.petersen_graph()
printGraphState(petersen)
nx.draw_networkx(petersen)


# nodes: 10
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# edges: 15
[(0, 1), (0, 4), (0, 5), (1, 2), (1, 6), (2, 3), (2, 7), (3, 8), (3, 4), (4, 9), (5, 8), (5, 7), (6, 8), (6, 9), (7, 9)]
# self-loops: 0

In [97]:
tutte  = nx.tutte_graph()
printGraphState(tutte)
nx.draw_networkx(tutte)


# nodes: 46
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45]
# edges: 69
[(0, 1), (0, 2), (0, 3), (1, 26), (1, 4), (2, 10), (2, 11), (3, 18), (3, 19), (4, 5), (4, 33), (5, 29), (5, 6), (6, 27), (6, 7), (7, 8), (7, 14), (8, 9), (8, 38), (9, 10), (9, 37), (10, 39), (11, 12), (11, 39), (12, 35), (12, 13), (13, 14), (13, 15), (14, 34), (15, 16), (15, 22), (16, 17), (16, 44), (17, 18), (17, 43), (18, 45), (19, 20), (19, 45), (20, 41), (20, 21), (21, 22), (21, 23), (22, 40), (23, 24), (23, 27), (24, 32), (24, 25), (25, 26), (25, 31), (26, 33), (27, 28), (28, 32), (28, 29), (29, 30), (30, 33), (30, 31), (31, 32), (34, 35), (34, 38), (35, 36), (36, 37), (36, 39), (37, 38), (40, 41), (40, 44), (41, 42), (42, 43), (42, 45), (43, 44)]
# self-loops: 0

In [98]:
maze = nx.sedgewick_maze_graph()
printGraphState(maze)
nx.draw_networkx(maze)


# nodes: 8
[0, 1, 2, 3, 4, 5, 6, 7]
# edges: 10
[(0, 2), (0, 5), (0, 7), (1, 7), (2, 6), (3, 4), (3, 5), (4, 5), (4, 6), (4, 7)]
# self-loops: 0

In [99]:
tet = nx.tetrahedral_graph()
printGraphState(tet)
nx.draw_networkx(tet)


# nodes: 4
[0, 1, 2, 3]
# edges: 6
[(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]
# self-loops: 0

In [128]:
K_5 = nx.complete_graph(6)
printGraphState(K_5)
nx.draw_networkx(K_5)


# nodes: 6
[0, 1, 2, 3, 4, 5]
# edges: 15
[(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
# self-loops: 0

In [129]:
K_3_5  = nx.complete_bipartite_graph(2,5)
printGraphState(K_3_5)
nx.draw_networkx(K_3_5)


# nodes: 7
[0, 1, 2, 3, 4, 5, 6]
# edges: 10
[(0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6)]
# self-loops: 0

In [149]:
barbell = nx.barbell_graph(4,8)
printGraphState(barbell)
nx.draw_networkx(barbell)


# nodes: 16
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
# edges: 21
[(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (12, 14), (12, 15), (13, 14), (13, 15), (14, 15)]
# self-loops: 0

In [158]:
lollipop = nx.lollipop_graph(8,2)
printGraphState(lollipop)
nx.draw_networkx(lollipop)


# nodes: 10
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# edges: 30
[(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (3, 4), (3, 5), (3, 6), (3, 7), (4, 5), (4, 6), (4, 7), (5, 6), (5, 7), (6, 7), (7, 8), (8, 9)]
# self-loops: 0

In [165]:
er = nx.erdos_renyi_graph(10,0.333)
printGraphState(er)
nx.draw_networkx(er)


# nodes: 10
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# edges: 13
[(0, 8), (0, 1), (0, 6), (1, 2), (1, 3), (1, 5), (2, 4), (2, 6), (2, 7), (3, 8), (3, 6), (4, 7), (7, 9)]
# self-loops: 0

In [171]:
ws = nx.watts_strogatz_graph(10,2,0.75)
printGraphState(ws)
nx.draw_networkx(ws)


# nodes: 10
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# edges: 10
[(0, 3), (0, 2), (0, 7), (1, 4), (3, 6), (4, 5), (4, 9), (7, 8), (7, 9), (8, 9)]
# self-loops: 0

In [177]:
red = nx.random_lobster(20,0.9,0.9)
printGraphState(red)
nx.draw_networkx(red)


# nodes: 87
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86]
# edges: 86
[(0, 1), (0, 30), (1, 32), (1, 2), (2, 34), (2, 3), (3, 36), (3, 4), (4, 5), (4, 38), (5, 40), (5, 6), (6, 42), (6, 7), (7, 8), (7, 44), (8, 9), (8, 46), (9, 48), (9, 10), (10, 50), (10, 11), (11, 52), (11, 12), (12, 13), (12, 54), (13, 14), (14, 56), (14, 15), (15, 16), (15, 58), (16, 17), (16, 60), (17, 18), (17, 62), (18, 64), (18, 19), (19, 20), (19, 66), (20, 67), (20, 21), (21, 69), (21, 22), (22, 71), (22, 23), (23, 24), (23, 73), (24, 25), (24, 75), (25, 26), (25, 77), (26, 27), (26, 79), (27, 81), (27, 28), (28, 83), (28, 29), (29, 85), (30, 31), (32, 33), (34, 35), (36, 37), (38, 39), (40, 41), (42, 43), (44, 45), (46, 47), (48, 49), (50, 51), (52, 53), (54, 55), (56, 57), (58, 59), (60, 61), (62, 63), (64, 65), (67, 68), (69, 70), (71, 72), (73, 74), (75, 76), (77, 78), (79, 80), (81, 82), (83, 84), (85, 86)]
# self-loops: 0

Write/Read data to/from file


In [179]:
#nx.write_gml(red,"./red.gml")

In [180]:
g = nx.read_gml("./red.gml")
printGraphState(red)
nx.draw_networkx(red)


# nodes: 87
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86]
# edges: 86
[(0, 1), (0, 30), (1, 32), (1, 2), (2, 34), (2, 3), (3, 36), (3, 4), (4, 5), (4, 38), (5, 40), (5, 6), (6, 42), (6, 7), (7, 8), (7, 44), (8, 9), (8, 46), (9, 48), (9, 10), (10, 50), (10, 11), (11, 52), (11, 12), (12, 13), (12, 54), (13, 14), (14, 56), (14, 15), (15, 16), (15, 58), (16, 17), (16, 60), (17, 18), (17, 62), (18, 64), (18, 19), (19, 20), (19, 66), (20, 67), (20, 21), (21, 69), (21, 22), (22, 71), (22, 23), (23, 24), (23, 73), (24, 25), (24, 75), (25, 26), (25, 77), (26, 27), (26, 79), (27, 81), (27, 28), (28, 83), (28, 29), (29, 85), (30, 31), (32, 33), (34, 35), (36, 37), (38, 39), (40, 41), (42, 43), (44, 45), (46, 47), (48, 49), (50, 51), (52, 53), (54, 55), (56, 57), (58, 59), (60, 61), (62, 63), (64, 65), (67, 68), (69, 70), (71, 72), (73, 74), (75, 76), (77, 78), (79, 80), (81, 82), (83, 84), (85, 86)]
# self-loops: 0

Analyse graphs


In [185]:
max(nx.connected_components(ws), key=len)


Out[185]:
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

In [187]:
sorted(nx.degree(lollipop).values())


Out[187]:
[1, 2, 7, 7, 7, 7, 7, 7, 7, 8]

In [189]:
nx.clustering(barbell)


Out[189]:
{0: 1.0,
 1: 1.0,
 2: 1.0,
 3: 0.5,
 4: 0.0,
 5: 0.0,
 6: 0.0,
 7: 0.0,
 8: 0.0,
 9: 0.0,
 10: 0.0,
 11: 0.0,
 12: 0.5,
 13: 1.0,
 14: 1.0,
 15: 1.0}

In [190]:
nx.degree(petersen)


Out[190]:
{0: 3, 1: 3, 2: 3, 3: 3, 4: 3, 5: 3, 6: 3, 7: 3, 8: 3, 9: 3}

In [192]:
nx.degree(petersen,0)


Out[192]:
3

In [198]:
sorted(barbell.degree([3,4]).values())


Out[198]:
[2, 4]

In [199]:
nx.draw_circular(g)



In [200]:
nx.draw_circular(tutte)



In [202]:
nx.draw_shell(g)



In [203]:
plt.savefig("./g.png")


<matplotlib.figure.Figure at 0x7f369d446990>

In [204]:
import os
os.getcwd()


Out[204]:
'/home/vagrant'

In [ ]: